﻿using System;
using CzfRow = System.Collections.Generic.Dictionary<string, string>;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Text;
//using LitJson;
using System.Collections;
using System.Reflection;
using System.Collections.Generic;

namespace CzfSDK
{
	public static class Tool
	{
		public static bool jsonPrettyPrint = true;

//		public static string ToJson(this object obj)
//		{
//			var w = new LitJson.JsonWriter ();
//			w.PrettyPrint = jsonPrettyPrint;
//			LitJson.JsonMapper.ToJson (obj, w);
//			w.TextWriter.Flush ();
//			return Tool.ToGB2312 (w.TextWriter.ToString ());
//		}

        public static List<T> ToList<T>(this object obj)
        {
            if (obj == null)
            {
                return null;
            }

            if (obj is object[])
            {
                var objs = (object[])obj;
                var list = new List<T>(objs.Length);
                for (int i = 0; i < objs.Length; i++)
                {
                    list.Add((T)objs[i]);
                }
                return list;
            }
            else
            {
                throw new Exception("错误的类型转换:" + obj.ToString());
            }
        }

		public static Hashtable JsonToHashtable(this string json)
		{
			var reader = LitJson.JsonMapper.ToObject(json);
			var dict = (IDictionary)reader;
			var ret = new Hashtable ();
			foreach (var k in dict.Keys) {
				var val = (LitJson.JsonData)dict [k];
				if (val.IsDouble)
					ret [k] = Convert.ToSingle((double)val);
				else if (val.IsString)
					ret [k] = (string)val;
				else if (val.IsInt)
					ret [k] = (int)val;
				else {
					throw new Exception ("未处理的类型:" + k + val);
				}
			}
			return ret;
		}

		public static string ToJson(this object obj, int space = 0)
		{	
			if (obj == null) {
				return "null";
			} else if (obj is Hashtable) {
				var ht = (Hashtable)obj;
				StringBuilder sb = new StringBuilder ();	
				sb.AppendLine (GetSpace (space) + "{");
				if (ht.Count > 0) {
					foreach (var k in ht.Keys) {
						sb.AppendLine (GetSpace (space + 4) + "\"" + k.ToString () + "\":" + ht [k].ToJson (space + 4) + ",");
					}
					sb.Length -= 2;
					sb.AppendLine ();
				}
				sb.AppendLine (GetSpace (space) + "}");
				return sb.ToString ();
			} else if (obj is IDictionary) {
				var ht = (IDictionary)obj;
				StringBuilder sb = new StringBuilder ();	
				sb.AppendLine (GetSpace (space) + "{");
				foreach (var k in ht.Keys) {
					sb.AppendLine (GetSpace (space + 4) + "\"" + k.ToString () + "\":" + ht [k].ToJson (space + 4));
				}
				sb.AppendLine (GetSpace (space) + "}");
				return sb.ToString ();
			} else if (obj is IList) {
				StringBuilder sb = new StringBuilder ();	
				var list = (IList)obj;
				sb.AppendLine (GetSpace (space) + "[");
				if (list.Count > 0) {
					foreach (var v in list) {
						sb.AppendLine (GetSpace (space + 4) + v.ToJson () + ",");
					}
					sb.Length -= 2;
				}
				sb.AppendLine ();
				sb.AppendLine (GetSpace (space) + "]");
				return sb.ToString ();
			} else if (obj is string) {
				return "\"" + obj + "\"";
			}else if (obj is DateTime) {
				return "\"" + obj.ToString() + "\"";
			} else {
				return obj.ToString ();
			}
		}

		public static void Fill<T>(this List<T> list, T item, int count)
		{
			for (int i = list.Count; i < count; i++) {
				list.Add(item);
			}
		}

		private static string GetSpace(int count){
			StringBuilder sb = new StringBuilder ();
			for (int i = 0; i < count; i++) {
				sb.Append (" ");
			}
			return sb.ToString ();
		}

		public static string GetVal(this CzfRow row, string key)
		{
			if (row.ContainsKey (key))
				return row[key];
			else
				return null;
		}

		public static T GetVal<T>(this Hashtable row, object key, T def = default(T))
		{
			if (row.ContainsKey (key))
				return (T)Convert.ChangeType(row[key], typeof(T));
			else
				return def;
		}

		public static T GetVal<T>(this CzfRow row, string key, T def = default(T))
		{
			if (row.ContainsKey (key))
				return (T)Convert.ChangeType(row[key], typeof(T));
			else
				return def;
		}

//		public static T GetVal<T>(this JsonData row, string key, T def = default(T))
//		{
//			var dict = (IDictionary)row;
//			if (dict.Contains(key))
//				return (T)Convert.ChangeType(dict[key].ToString(), typeof(T));
//			else
//				return def;
//		}

		public static T CzfGetAttribute<T>(this Type type, bool inherit = true) where T : Attribute
		{
			var l = type.GetCustomAttributes (typeof(T), inherit);
			if (l == null || l.Length == 0)
				return default(T);
			else
				return (T)l[0];
		}

		public static T CzfGetAttribute<T>(this FieldInfo type, bool inherit = false) where T : Attribute
		{
			var l = type.GetCustomAttributes (typeof(T), inherit);
			if (l == null || l.Length == 0)
				return default(T);
			else
				return (T)l[0];
		}

		public static void AddDict(this Dictionary<int, int> dict, int key, int addVal, int defVal = 0)
		{
			if (dict.ContainsKey (key))
				dict [key] += addVal;
			else
				dict [key] = defVal + addVal;
		}
	}
}

